from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.edge.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.edge.service import Service
import random
import time

# -------------------------- 基础配置参数（通用配置）--------------------------
EDGE_BINARY_PATH = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
EDGE_DRIVER_PATH = r"G:\python实战\driver\msedgedriver.exe"
INITIAL_MANUAL_OPERATE_TIME = 50  # 首次手动操作时间（秒）
MIN_WAIT_TIME = 1  # 每条评论最小间隔（秒）
MAX_WAIT_TIME = 5  # 每条评论最大间隔（秒）
VERIFY_CODE_SLEEP_TIME = 25  # 验证码处理休眠时间（秒）
RETURN_LIST_WAIT_TIME = 5  # 返回关注列表的等待时间（秒）


# --------------------------------------------------------------------------------


def get_current_uploader_name(driver, wait):
    """获取当前视频的上传者（博主）名称"""
    try:
        uploader_name = driver.execute_script("""
            var authorCard = document.querySelector('div.author-card-user-name');
            return authorCard ? authorCard.innerText.trim() : '';
        """)
        if uploader_name:
            return uploader_name

        print("⚠️  主方法获取博主名称失败，尝试备用 XPath 方案...")
        uploader_element = wait.until(
            EC.presence_of_element_located((By.XPATH, "//div[contains(@class, 'author-card-user-name')]"))
        )
        return uploader_element.text.strip()
    except Exception as e:
        print(f"⚠️  无法获取当前视频的博主名称: {e}")
        return "未知博主"


def send_comments_to_bloggers(driver, wait,
                              target_bloggers,  # 目标博主列表（必填）
                              comment_contents,  # 评论内容列表（必填，如["内容1", "内容2"]，随机选取）
                              comment_count):  # 每个博主需要发送的评论总数（必填）
    """
    通用评论方法：向指定博主列表发送指定内容的评论，支持自定义内容和次数
    返回：该组成功发送的总评论数、该组成功完成评论的博主数量
    """
    total_bloggers = len(target_bloggers)
    blogger_index = 0  # 当前处理的博主索引
    group_comments_sent = 0  # 该组成功发送的总评论数
    group_successful_bloggers = 0  # 该组成功完成评论的博主数量

    while blogger_index < total_bloggers:
        blogger_name = target_bloggers[blogger_index]
        blogger_idx = blogger_index + 1  # 显示用序号（从1开始）
        processed = False  # 当前博主是否处理成功的标志

        print(f"\n==================================================")
        print(f"📢 开始处理第 {blogger_idx}/{total_bloggers} 个博主：{blogger_name}")
        print(f"📝 评论内容池：{comment_contents}，需发送 {comment_count} 条")
        print(f"==================================================")

        # 对当前博主循环重试，直到成功处理
        while not processed:
            try:
                # 1. 定位并点击目标博主（需在关注列表中）
                print(f"🔍 正在关注列表中查找博主：{blogger_name}...")
                blogger_element = wait.until(
                    EC.element_to_be_clickable((By.XPATH,
                                                f"//li[contains(@class, 'pZz7hFIi')]//div[contains(@class, 'ILK2RAD5')]//span[text()='{blogger_name}']"))
                )
                blogger_element.click()
                print(f"✅ 已点击进入博主 {blogger_name} 的页面")
                time.sleep(random.uniform(2, 3))  # 等待页面加载

                # 2. 手动点击视频并打开评论区
                print(f"\n⌛ 请在8秒内手动点击该博主的一个视频并打开评论区（确保评论框可见）")
                for i in range(8, 0, -1):
                    print(f"视频准备倒计时：{i}秒", end="\r")
                    time.sleep(1)

                # 3. 发送指定次数和内容的评论
                uploader_name = get_current_uploader_name(driver, wait)
                print(f"\n👤 确认当前视频博主：{uploader_name}，开始发送评论...")

                success_count = 0  # 成功计数器
                current_attempt = 1  # 当前尝试序号

                while success_count < comment_count:
                    # 从评论内容池中随机选一个内容（如果是单元素列表则固定发送该内容）
                    comment_content = random.choice(comment_contents)

                    try:
                        # 定位评论输入框
                        comment_input_div = wait.until(
                            EC.presence_of_element_located((By.CSS_SELECTOR, "div.public-DraftStyleDefault-block"))
                        )

                        comment_input_div.click()
                        time.sleep(random.uniform(0.2, 0.5))
                        comment_input_div.send_keys(comment_content)
                        print(f"📝 尝试发送第 {current_attempt} 条评论：'{comment_content}'")
                        time.sleep(random.uniform(0.3, 0.7))
                        comment_input_div.send_keys(Keys.ENTER)
                        print(f"✅ 第 {current_attempt} 条评论发送成功！当前成功数：{success_count + 1}/{comment_count}")

                        success_count += 1
                        current_attempt += 1
                        # 评论间隔
                        wait_time = random.uniform(MIN_WAIT_TIME, MAX_WAIT_TIME)
                        time.sleep(wait_time)

                    except Exception as e:
                        print(f"\n❌ 第 {current_attempt} 条评论发送失败：{e}")
                        print(f"⚠️  可能触发验证码！将休眠 {VERIFY_CODE_SLEEP_TIME} 秒，请手动处理...")

                        for i in range(VERIFY_CODE_SLEEP_TIME, 0, -1):
                            print(f"⏳ 处理倒计时：{i}秒", end="\r")
                            time.sleep(1)

                        print(f"\n✅ 休眠结束，重新尝试发送第 {current_attempt} 条评论...")
                        uploader_name = get_current_uploader_name(driver, wait)
                        continue

                # 所有评论发送成功，标记当前博主处理完成
                print(f"\n🎉 博主 {uploader_name} 的 {comment_count} 条评论已全部发送成功！")
                processed = True  # 退出当前博主的重试循环
                # 累加该组的统计数据
                group_successful_bloggers += 1
                group_comments_sent += comment_count

            except Exception as e:
                print(f"\n❌ 处理博主 {blogger_name} 时发生错误：{e}")
                print(f"⚠️  可能未回到关注列表！将等待 {RETURN_LIST_WAIT_TIME} 秒，请返回关注列表后重试...")

                # 等待用户返回关注列表
                for i in range(RETURN_LIST_WAIT_TIME, 0, -1):
                    print(f"⏳ 返回列表倒计时：{i}秒", end="\r")
                    time.sleep(1)
                print(f"\n🔄 重新尝试处理博主 {blogger_name}...")
                # 不修改processed，继续重试当前博主

        # 当前博主处理成功，等待返回关注列表
        print(f"\n⌛ 请在 {RETURN_LIST_WAIT_TIME} 秒内手动返回到「关注列表」页面（准备处理下一个博主）")
        for i in range(RETURN_LIST_WAIT_TIME, 0, -1):
            print(f"返回列表倒计时：{i}秒", end="\r")
            time.sleep(1)
        print("\n✅ 准备处理下一个博主...")

        blogger_index += 1  # 处理下一个博主

    print(f"\n🎉 目标博主列表（共 {total_bloggers} 个）的评论任务已全部完成！")
    # 返回该组的统计结果
    return group_comments_sent, group_successful_bloggers


# -------------------------- 主程序（调用通用方法+统计总结果）--------------------------
if __name__ == "__main__":
    # 初始化浏览器
    edge_options = Options()
    edge_options.binary_location = EDGE_BINARY_PATH

    try:
        edge_service = Service(executable_path=EDGE_DRIVER_PATH)
        driver = webdriver.Edge(service=edge_service, options=edge_options)
        driver.maximize_window()
        wait = WebDriverWait(driver, 15)
        print("✅ Edge浏览器启动成功！")
    except Exception as e:
        print(f"❌ EdgeDriver初始化失败：{e}")
        exit()

    # 初始化全局统计计数器
    total_comments_sent = 0  # 所有组成功发送的总评论数
    successful_bloggers = 0  # 所有组成功完成评论的博主总数

    try:
        driver.get("https://www.douyin.com/")
        print("🌐 已打开抖音网页版，请手动登录（若未登录）...")
        time.sleep(5)

        print(f"\n⌛ 请在 {INITIAL_MANUAL_OPERATE_TIME} 秒内完成以下操作：")
        print("1. 登录抖音账号")
        print("2. 导航到你的「关注列表」页面（确保能看到所有要评论的博主）")
        for i in range(INITIAL_MANUAL_OPERATE_TIME, 0, -1):
            print(f"倒计时：{i}秒", end="\r")
            time.sleep(1)
        print("\n✅ 手动操作时间结束，开始执行评论任务...")

        # -------------------------- 示例1：发送随机数字给第一组博主 --------------------------
        bloggers_group1 = [
            "小庄同学",
            "小飞猪",
            "李子酸还是甜",
            "扶摇Funny",
            "单挑主播泡椒",
            "美扶摇",
            "火影小奇倪",
            "一袋米扛几楼",
            "爱玩王者的小林",
            "楸楸",
            "春笋",
            "帅可心",
            "爱打王者的小桔梗",
            "宠粉小羊羔",
            "五千",
            "凡生",
            "三只番茄（帅东东）"
        ]
        random_num_comments = [str(random.randint(1, 100)) for _ in range(100)]
        # 调用方法并接收该组统计结果
        group1_comments, group1_bloggers = send_comments_to_bloggers(
            driver=driver,
            wait=wait,
            target_bloggers=bloggers_group1,
            comment_contents=random_num_comments,
            comment_count=5
        )
        # 累加至全局统计
        total_comments_sent += group1_comments
        successful_bloggers += group1_bloggers

        # -------------------------- 示例2：发送自定义内容给第二组博主 --------------------------
        bloggers_group2 = [
            "韭菜鹤顶红",
            "莉瑶要努力鸭、",
            "乔岸礼",
            "鸭妹妹",
            "陈木夕",
            "我不吃牛肉",
            "是锦鲤呀"
        ]
        custom_comments = [
            "一直没有被分分到，但每天坚持打卡~加油！！！",
            "还没被分分到，坚持打卡，愿意返图喔",
            "打卡打卡，每天坚持打卡求分分~",
            "主包发财发财发财~"
        ]
        # 调用方法并接收该组统计结果
        group2_comments, group2_bloggers = send_comments_to_bloggers(
            driver=driver,
            wait=wait,
            target_bloggers=bloggers_group2,
            comment_contents=custom_comments,
            comment_count=2  # 注意：此处参数与注释一致（原注释1条，参数2条，已修正）
        )
        # 累加至全局统计
        total_comments_sent += group2_comments
        successful_bloggers += group2_bloggers

        # -------------------------- 输出最终统计结果 --------------------------
        print("\n" + "="*50)
        print("📊 全局评论任务统计结果")
        print("="*50)
        print(f"✅ 成功完成评论的博主总数：{successful_bloggers} 个")
        print(f"✅ 成功发送的总评论数：{total_comments_sent} 条")
        print("="*50)

    except KeyboardInterrupt:
        print("\n\n🛑 用户手动停止了脚本。")
        # 即使手动停止，也输出已统计的结果
        print("\n" + "="*50)
        print("📊 截至停止时的统计结果")
        print("="*50)
        print(f"✅ 成功完成评论的博主总数：{successful_bloggers} 个")
        print(f"✅ 成功发送的总评论数：{total_comments_sent} 条")
        print("="*50)
    except Exception as e:
        print(f"\n\n❌ 脚本执行发生未知异常：{e}")
        # 异常时也输出已统计的结果
        print("\n" + "="*50)
        print("📊 截至异常时的统计结果")
        print("="*50)
        print(f"✅ 成功完成评论的博主总数：{successful_bloggers} 个")
        print(f"✅ 成功发送的总评论数：{total_comments_sent} 条")
        print("="*50)
    finally:
        driver.quit()
        print("\n🔒 浏览器已关闭！")